package com.sk.web;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.sk.util.convert.StringBlankConverter;
import com.sk.web.aop.AccessAspect;
import com.sk.web.aop.AccessLogHandler;
import com.sk.web.aop.AuthPublic;
import com.sk.web.exception.GlobalExceptionHandler;
import com.sk.web.jackson.DateConverter;
import com.sk.web.jackson.DateSerializer;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Info;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Primary;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Date;

/**
 * 基础Web配置类。
 * <p/> 默认加载swagger{@link RestController}
 *
 * @author smy
 */
@Slf4j
@EnableAsync
@Configuration
@Import(value = {AccessAspect.class, AuthPublic.class, GlobalExceptionHandler.class})
public class WebConfig {

    //自定义日期接收转换器,解决client时区不一致
    @Bean
    public DateConverter dateConverter() {
        return new DateConverter();
    }

    @Bean
    public StringBlankConverter strConverter() {
        return new StringBlankConverter();
    }

    //自定义jackson转换工具
    @Bean
    @Primary
    @ConditionalOnMissingBean(ObjectMapper.class)
    public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {
        ObjectMapper objectMapper = builder.createXmlMapper(false).build();
        SimpleModule simpleModule = new SimpleModule();
        //大数字转字符串,解决js精度丢失问题
        simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
        simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);
        simpleModule.addSerializer(BigDecimal.class, ToStringSerializer.instance);
        simpleModule.addSerializer(BigInteger.class, ToStringSerializer.instance);
        //日期转时间戳,解决client时区不一致
        simpleModule.addSerializer(Date.class, new DateSerializer());
        objectMapper.registerModule(simpleModule);
        return objectMapper;
    }

    @Bean
    @Primary
    @ConditionalOnMissingBean(AccessLogHandler.class)
    public AccessLogHandler accessArgsHandler() {
        return new AccessLogHandler();
    }

    @Bean
    @ConditionalOnMissingBean(OpenAPI.class)
    public OpenAPI springOpenAPI() {
        return new OpenAPI().info(new Info().title("All RestController").description("SpringDoc Application default").version("v1"));
    }


}
